package interfaces.app;

import exceptions.CreatingProcessException;
import interfaces.data.IHandle;
import interfaces.data.IStatus;

import java.util.Collection;

/**
 * Interface of the process which could have children and running in separate thread.
 * <br/>
 * Created: 11.10.11
 *
 * @author Martin Štulc (<a href="mailto:martin.stulc@gmail.com">martin.stulc@gmail.com</a>)
 * @version 1.0
 */
public interface IProcess extends Runnable
{
    /**
     * Return a status of the process.
     *
     * @return the process status
     */
    IStatus getStatus();

    /**
     * Return a handle of the process.
     *
     * @return the process handle
     */
    IHandle getHandle();

    /**
     * Return PID of the process.
     *
     * @return the process PID
     */
    int getPid();

    /**
     * Create a child process. Use ProcessCreator class for that.
     *
     * @param handle handle of process
     * @return created process
     * @throws CreatingProcessException if will be error in creating of process
     */
    IProcess createChildProcess(IHandle handle) throws CreatingProcessException;

    /**
     * Start the process.
     *
     * @return true if start was successful; otherwise false
     */
    boolean startProcess();

    /**
     * Wait to child which has the pid.
     *
     * @param pid the pid of the child
     */
    void waitToChild(final int pid);

    /**
     * Wait to all children.
     */
    void waitToAllChildren();

    /**
     * Regular quiting of the process. Send quit to all children and waiting to them.
     *
     * @return true if process was exited; otherwise false (probably must call terminate)
     */
    boolean quit();

    /**
     * Terminate the process and all his children.
     */
    void terminate();

    /**
     * Return a parent process.
     *
     * @return the parent process
     */
    IProcess getParent();

    /**
     * Return a root process.
     *
     * @return the root process.
     */
    IProcess getRootProcess();

    /**
     * A collection of opened streams of the process.
     *
     * @return the opened streams
     */
    Collection<IStream> getOpenedStreams();

    /**
     * A collection of opened streams of the process and all children.
     *
     * @return the opened streams
     */
    Collection<IStream> getOpenedStreamsRecursively();

    /**
     * A collection of opened streams of the process which are opened exclusively.
     *
     * @return the opened exclusive streams
     */
    Collection<IStream> getOpenedExclusiveStream();

    /**
     * A collection of opened streams of the process and all children which are opened exclusively.
     *
     * @return the opened exclusive streams
     */
    Collection<IStream> getOpenedExclusiveStreamRecursively();

    /**
     * Return true if the process ended.
     *
     * @return true if the process ended; otherwise false
     */
    Boolean hasEndStatus();

    /**
     * Return collection of the children of the process.
     *
     * @return collection of the children
     */
    Collection<IProcess> getChildren();

    /**
     * Return collection of all children and their children of the process.
     *
     * @return collection of all children and their children
     */
    Collection<IProcess> getChildrenRecursively();
}
